﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapEntities;
using System.Data.OleDb;
using Microsoft.AnalysisServices;
using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.AnalysisServices.AdomdClient;
using System.Data;

namespace ServerPlatform.DataProvider.Providers
{
    public class AnalysisServicesDataProvider : BaseDataProvider
    {
        public override List<DALEntities.ViewSchema> GetViews()
        {
            return null;
        }

        public override void Connect(string connectionString)
        {
            
        }

        public override DALEntities.ViewResult GetViewResult(DALEntities.ViewRequest request)
        {
            AdomdConnection conn = new AdomdConnection(GetProviderConnStr(request.ConnectionString));
            conn.Open();
            string cmdStr = string.Format("select [Measures].members on columns, {0}.members on rows from [{1}]",
                GetConnStrField(request.ConnectionString, "geodimension"),
                 request.ViewName);
            if (request.ExtraData != null && !string.IsNullOrEmpty(request.ExtraData.ToString()))
                cmdStr += "where " + request.ExtraData.ToString();
            AdomdCommand cmd = new AdomdCommand(cmdStr, conn);
            DALEntities.ViewResult result = new DALEntities.ViewResult();
            result.RequestID = request.ID;
            AdomdDataAdapter adapter = new AdomdDataAdapter(cmd);
            DataTable table = new DataTable("MSASRESULT");
            adapter.Fill(table);
            if (table.Rows.Count > 0)
                table.Rows.RemoveAt(0);
            if (table.Columns.Count > 0) 
                table.Columns[0].ColumnName = "_GeoDimension";
            for (int i = 1; i < table.Columns.Count; i++)
            {
                table.Columns[i].ColumnName = table.Columns[i].ColumnName.Replace("[Measures].", "").Replace("[", "").Replace("]", "");
            }
            result.Data = table.DefaultView;
            conn.Close();
            return result;
        }

        public override DALEntities.ProviderSource Source
        {
            get { return DALEntities.ProviderSource.MSAS; }
        }

        private string GetProviderConnStr(string connStr)
        {
            string [] list = connStr.Split(';');
            StringBuilder sb = new StringBuilder();
            foreach (string item in list)
            {
                if (!item.ToLowerInvariant().StartsWith("geodimension"))
                    sb.Append(item + ";");
            }
            return sb.ToString();
            
        }

        private string GetConnStrField(string connStr, string field)
        {
            string[] list = connStr.Split(';');
            StringBuilder sb = new StringBuilder();
            foreach (string item in list)
            {
                if (item.ToLowerInvariant().StartsWith(field.ToLowerInvariant()))
                {
                    string[] values = item.Split('=');
                    if (values.Length > 1)
                        return values[1];
                    else return "";
                }
            }
            return "";

        }

        public override DALEntities.ViewSchemaList GetSchema(DALEntities.SchemaRequest request)
        {
            Server server = new Server();
            server.Connect(GetProviderConnStr(request.ConnectionString));
            DALEntities.ViewSchemaList result = new DALEntities.ViewSchemaList();

            foreach (Database db in server.Databases)
            {
                foreach (Cube c in db.Cubes)
                {
                    DALEntities.ViewSchema sc = new DALEntities.ViewSchema();
                    sc.Name = c.Name;
                    sc.Columns.Add(new DALEntities.Column() { Type = DALEntities.DataType.Integer, Name = "_GeoDimension" });
                    SetColumns(c, sc);
                    result.Add(sc);
                }
            }

            server.Disconnect(true);
            return result;

        }

        private void SetColumns(Cube cube, DALEntities.ViewSchema sc)
        {
            foreach (MeasureGroup group in cube.MeasureGroups)
            {
                foreach (Microsoft.AnalysisServices.Measure m in group.Measures)
                {
                    sc.Columns.Add(new DALEntities.Column() { Name = m.Name, Description = m.Description, Type = getMeasureType(m) });
                    
                }
            }
        }

        private DALEntities.DataType getMeasureType(Microsoft.AnalysisServices.Measure m)
        {
            switch (m.DataType)
            {
                case MeasureDataType.BigInt:                
                    {
                        return DALEntities.DataType.Int64;
                    }
                case MeasureDataType.Currency:
                case MeasureDataType.Single:
                    {
                        return DALEntities.DataType.Decimal;
                    }
                case MeasureDataType.Double:
                    {
                        return DALEntities.DataType.Double;
                    }
                case MeasureDataType.Integer:
                case MeasureDataType.SmallInt:
                case MeasureDataType.TinyInt:
                case MeasureDataType.UnsignedInt:
                case MeasureDataType.UnsignedSmallInt:
                case MeasureDataType.UnsignedTinyInt: return DALEntities.DataType.Integer;
                case MeasureDataType.WChar: return DALEntities.DataType.String;
                default: return DALEntities.DataType.Unknown;
            }
        }



        public override MapEntities.Shape GetShape(object data, ShapeItemBindingRule rule)
        {
            return null;
        }
    }
}
